package com.bjsdzk.collector.serviceImp;

import java.util.HashMap;
import java.util.Map;


import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Service;

import com.bjsdzk.collector.platform.coap.utils.Constant;
import com.bjsdzk.collector.platform.coap.utils.HttpsUtil;
import com.bjsdzk.collector.platform.coap.utils.JsonUtil;
import com.bjsdzk.collector.platform.coap.utils.StreamClosedHttpResponse;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;

@Service
public class TelecomService {
	
	private static Logger logger = LoggerFactory.getLogger(TelecomService.class);

    @Autowired
    private MongoTemplate mongoTemplate;
    
	private volatile String accessToken ;
	
	private volatile String refreshToken ;
	
	
    @SuppressWarnings({ "unchecked", "resource" })
	public String getToken() throws Exception  {
    	
    	  String appId = Constant.APPID;
          String secret = Constant.SECRET;
          String urlLogin = Constant.APP_AUTH;
          
          HttpsUtil httpsUtil = new HttpsUtil();
          httpsUtil.initSSLConfigForTwoWay();

          Map<String, String> paramLogin = new HashMap<>();
          paramLogin.put("appId", appId);
          paramLogin.put("secret", secret);

          StreamClosedHttpResponse responseLogin = httpsUtil.doPostFormUrlEncodedGetStatusLine(urlLogin, paramLogin);

          logger.info("StatusLine:"+responseLogin.getStatusLine()+" response content:"+responseLogin.getContent());

          Map<String, String> data = new HashMap<>();
          data = JsonUtil.jsonString2SimpleObj(responseLogin.getContent(), data.getClass());
          accessToken=data.get("accessToken");
          refreshToken=data.get("refreshToken");
          return data.get("accessToken");
	}
    
    @SuppressWarnings({ "unchecked", "resource" })
    public String refreshToken() throws Exception {
        // Two-Way Authentication
        HttpsUtil httpsUtil = new HttpsUtil();
        httpsUtil.initSSLConfigForTwoWay();

        String appId = Constant.APPID;
        String secret = Constant.SECRET;
        String urlRefreshToken = Constant.REFRESH_TOKEN; 

        Map<String, Object> param_reg = new HashMap<>();
        param_reg.put("appId", appId);
        param_reg.put("secret", secret);
        param_reg.put("refreshToken", refreshToken);

        String jsonRequest = JsonUtil.jsonObj2Sting(param_reg);
        StreamClosedHttpResponse bodyRefreshToken = httpsUtil.doPostJsonGetStatusLine(urlRefreshToken, jsonRequest);

        Map<String, String> data = new HashMap<>();
        data = JsonUtil.jsonString2SimpleObj(bodyRefreshToken.getContent(), data.getClass());
        logger.info("StatusLine:"+bodyRefreshToken.getStatusLine()+" response content:"+bodyRefreshToken.getContent());
        accessToken=data.get("accessToken");
        refreshToken=data.get("refreshToken");
        return data.get("accessToken");
    }
    
    public String getToken1()   {
        return accessToken;
	}
    
    
    /** 查询单个设备信息*/
    @SuppressWarnings({ "unchecked", "resource" })
    public String queryDeviceData(String deviceId) throws Exception {
        HttpsUtil httpsUtil = new HttpsUtil();
        httpsUtil.initSSLConfigForTwoWay();


        //Please make sure that the following parameter values have been modified in the Constant file.
        String appId = Constant.APPID;

        //please replace the deviceId, when you use the demo.
        String urlQueryDeviceData = Constant.QUERY_DEVICE_DATA + "/" + deviceId;

        Map<String, String> paramQueryDeviceData = new HashMap<>();
        paramQueryDeviceData.put("appId", appId);

        Map<String, String> header = new HashMap<>();
        header.put(Constant.HEADER_APP_KEY, appId);
        header.put(Constant.HEADER_APP_AUTH, "Bearer" + " " + accessToken);
        
        StreamClosedHttpResponse bodyQueryDeviceData = httpsUtil.doGetWithParasGetStatusLine(urlQueryDeviceData,
                paramQueryDeviceData, header);
        Map<String, String> data = new HashMap<>();
        data = JsonUtil.jsonString2SimpleObj(bodyQueryDeviceData.getContent(), data.getClass());
        mongoTemplate.save(data,"telecom");
        logger.info("StatusLine:"+bodyQueryDeviceData.getStatusLine()+" response content:"+bodyQueryDeviceData.getContent());
        return bodyQueryDeviceData.getContent();
    }

    @SuppressWarnings({  "resource" })
    public String queryDevices(String deviceId,String gatewayId) throws Exception {
        // Two-Way Authentication
        HttpsUtil httpsUtil = new HttpsUtil();
        httpsUtil.initSSLConfigForTwoWay();

        //Please make sure that the following parameter values have been modified in the Constant file.
        String appId = Constant.APPID;
        String urlQueryDeviceCapabilities = Constant.QUERY_DEVICE_CAPABILITIES;

        Map<String, String> paramQueryDeviceCapabilities = new HashMap<>();
        paramQueryDeviceCapabilities.put("deviceId", deviceId);
        paramQueryDeviceCapabilities.put("gatewayId", gatewayId);

        Map<String, String> header = new HashMap<>();
        header.put(Constant.HEADER_APP_KEY, appId);
        header.put(Constant.HEADER_APP_AUTH, "Bearer" + " " + accessToken);
        
        StreamClosedHttpResponse bodyQueryDeviceCapabilities = httpsUtil.doGetWithParasGetStatusLine(
                urlQueryDeviceCapabilities, paramQueryDeviceCapabilities, header);

        logger.info("StatusLine:"+bodyQueryDeviceCapabilities.getStatusLine()+" response content:"+bodyQueryDeviceCapabilities.getContent());
        return bodyQueryDeviceCapabilities.getContent();
    }
    
    /**4.3.3 查询设备历史数据*/
    @SuppressWarnings({  "resource" })
    public String queryDataHistory(String deviceId,String gatewayId,String pageNo,String pageSize,String startTime,String endTime) throws Exception {
 	   // Two-Way Authentication
     HttpsUtil httpsUtil = new HttpsUtil();
     httpsUtil.initSSLConfigForTwoWay();


     //Please make sure that the following parameter values have been modified in the Constant file.
     String appId = Constant.APPID;
     String urlQueryDeviceHistoryData = Constant.QUERY_DEVICE_HISTORY_DATA;

     Map<String, String> paramQueryDeviceHistoryData = new HashMap<>();
     paramQueryDeviceHistoryData.put("deviceId", deviceId);
     paramQueryDeviceHistoryData.put("gatewayId", gatewayId);
     paramQueryDeviceHistoryData.put("pageNo", pageNo);
     paramQueryDeviceHistoryData.put("pageSize", pageSize);
     if(StringUtils.isNotEmpty(startTime)&&StringUtils.isNotEmpty(startTime)) {
    	 paramQueryDeviceHistoryData.put("startTime", startTime);
    	 paramQueryDeviceHistoryData.put("endTime", endTime);
     }
     Map<String, String> header = new HashMap<>();
     header.put(Constant.HEADER_APP_KEY, appId);
     header.put(Constant.HEADER_APP_AUTH, "Bearer" + " " + accessToken);
     
     StreamClosedHttpResponse bodyQueryDeviceHistoryData = httpsUtil.doGetWithParasGetStatusLine(
             urlQueryDeviceHistoryData, paramQueryDeviceHistoryData, header);

     logger.info("StatusLine:"+bodyQueryDeviceHistoryData.getStatusLine()+" response content:"+bodyQueryDeviceHistoryData.getContent());
     return bodyQueryDeviceHistoryData.getContent();
 }
    
    /**订阅平台
     * @return
     * @throws Exception
     */
    @SuppressWarnings({  "resource" })
    public String subscribeNotify() throws Exception {
        // Two-Way Authentication
        HttpsUtil httpsUtil = new HttpsUtil();
        httpsUtil.initSSLConfigForTwoWay();

        //Please make sure that the following parameter values have been modified in the Constant file.
        String appId = Constant.APPID;
        String urlSubscribe = Constant.SUBSCRIBE_NOTIFYCATION;
        

        String callbackurl_deviceDataChanged = Constant.DEVICE_DATA_CHANGED_CALLBACK_URL;
        String notifyType_deviceDataChanged = Constant.DEVICE_DATA_CHANGED;

        Map<String, Object> paramSubscribe_deviceDataChanged = new HashMap<>();
        paramSubscribe_deviceDataChanged.put("notifyType", notifyType_deviceDataChanged);
        paramSubscribe_deviceDataChanged.put("callbackurl", callbackurl_deviceDataChanged);

        String jsonRequest_deviceDataChanged = JsonUtil.jsonObj2Sting(paramSubscribe_deviceDataChanged);

        Map<String, String> header_deviceDataChanged = new HashMap<>();
        header_deviceDataChanged.put(Constant.HEADER_APP_KEY, appId);
        header_deviceDataChanged.put(Constant.HEADER_APP_AUTH, "Bearer" + " " + accessToken);

        HttpResponse httpResponse_deviceDataChanged = httpsUtil.doPostJson(urlSubscribe, header_deviceDataChanged, jsonRequest_deviceDataChanged);

        String bodySubscribe_deviceDataChanged = httpsUtil.getHttpResponseBody(httpResponse_deviceDataChanged);

        logger.info("StatusLine:"+httpResponse_deviceDataChanged.getStatusLine()+" response content:"+bodySubscribe_deviceDataChanged);
        return bodySubscribe_deviceDataChanged;
    }
    
    /**注册设备
     * @return
     * @throws Exception
     */
    @SuppressWarnings({ "resource" })
    public String regDirectDevice(String verifyCode,String nodeId,String name,String location) throws Exception {
        HttpsUtil httpsUtil = new HttpsUtil();
        httpsUtil.initSSLConfigForTwoWay();


        //Please make sure that the following parameter values have been modified in the Constant file.
		String appId = Constant.APPID;
		String urlReg = Constant.REGISTER_DEVICE;

        //please replace the verifyCode and nodeId and timeout, when you use the demo.
        Integer timeout = 0;
        
        Map<String, Object> paramModifyDeviceInfo = new HashMap<>();
        paramModifyDeviceInfo.put("name", name);
        paramModifyDeviceInfo.put("manufacturerId", "0003");
        paramModifyDeviceInfo.put("manufacturerName", "XIYU");
        paramModifyDeviceInfo.put("location", location);
        paramModifyDeviceInfo.put("deviceType", "AFD");
        paramModifyDeviceInfo.put("model", "XYF32i3");
        paramModifyDeviceInfo.put("protocolType", "CoAP");
        

        Map<String, Object> paramReg = new HashMap<>();
        paramReg.put("verifyCode", verifyCode.toUpperCase());
        paramReg.put("nodeId", nodeId.toUpperCase());
        paramReg.put("timeout", timeout);
        paramReg.put("deviceInfo", paramModifyDeviceInfo);

        String jsonRequest = JsonUtil.jsonObj2Sting(paramReg);

        Map<String, String> header = new HashMap<>();
        header.put(Constant.HEADER_APP_KEY, appId);
        header.put(Constant.HEADER_APP_AUTH, "Bearer" + " " + accessToken);

        StreamClosedHttpResponse responseReg = httpsUtil.doPostJsonGetStatusLine(urlReg, header, jsonRequest);

        logger.info("StatusLine:"+responseReg.getStatusLine()+" response content:"+responseReg.getContent());
        return responseReg.getContent();
    }
    
    /**注册设备
     * @return
     * @throws Exception
     */
    @SuppressWarnings({ "resource" })
    public String regDirectrrrrrrDevice(String verifyCode,String nodeId,String name,String location) throws Exception {
        HttpsUtil httpsUtil = new HttpsUtil();
        httpsUtil.initSSLConfigForTwoWay();


        //Please make sure that the following parameter values have been modified in the Constant file.
		String appId = Constant.APPID;
		String urlReg = Constant.REGISTER_DEVICE;

        //please replace the verifyCode and nodeId and timeout, when you use the demo.
        Integer timeout = 0;
        
        Map<String, Object> paramModifyDeviceInfo = new HashMap<>();
        paramModifyDeviceInfo.put("name", name);
        paramModifyDeviceInfo.put("manufacturerId", "bhsiot");
        paramModifyDeviceInfo.put("manufacturerName", "bhsiot");
        paramModifyDeviceInfo.put("location", location);
        paramModifyDeviceInfo.put("deviceType", "bhside2");
        paramModifyDeviceInfo.put("model", "bhside2");
        paramModifyDeviceInfo.put("protocolType", "CoAP");

        Map<String, Object> paramReg = new HashMap<>();
        paramReg.put("verifyCode", verifyCode.toUpperCase());
        paramReg.put("nodeId", nodeId.toUpperCase());
        paramReg.put("timeout", timeout);
        paramReg.put("deviceInfo", paramModifyDeviceInfo);

        String jsonRequest = JsonUtil.jsonObj2Sting(paramReg);

        Map<String, String> header = new HashMap<>();
        header.put(Constant.HEADER_APP_KEY, appId);
        header.put(Constant.HEADER_APP_AUTH, "Bearer" + " " + accessToken);

        StreamClosedHttpResponse responseReg = httpsUtil.doPostJsonGetStatusLine(urlReg, header, jsonRequest);

        logger.info("StatusLine:"+responseReg.getStatusLine()+" response content:"+responseReg.getContent());
        return responseReg.getContent();
    }
    
    /**4.2.2 查询设备激活状态
     * @param deviceId
     * @return
     * @throws Exception
     */
    @SuppressWarnings({ "resource" })
    public String queryDeviceStatus(String deviceId) throws Exception {
        // Two-Way Authentication
        HttpsUtil httpsUtil = new HttpsUtil();
        httpsUtil.initSSLConfigForTwoWay();

        //Please make sure that the following parameter values have been modified in the Constant file.
		String appId = Constant.APPID;

        String urlDeviceActivationStatus = Constant.QUERY_DEVICE_ACTIVATION_STATUS + "/" + deviceId;

        Map<String, String> header = new HashMap<>();
        header.put(Constant.HEADER_APP_KEY, appId);
        header.put(Constant.HEADER_APP_AUTH, "Bearer" + " " + accessToken);

        StreamClosedHttpResponse bodyDeviceActivationStatus = httpsUtil.doGetWithParasGetStatusLine(
                urlDeviceActivationStatus, null, header);

        logger.info("StatusLine:"+bodyDeviceActivationStatus.getStatusLine()+" response content:"+bodyDeviceActivationStatus.getContent());
        return bodyDeviceActivationStatus.getContent();
    }
    /**删除直连设备
     * @return
     * @throws Exception
     */
    @SuppressWarnings({  "resource" })
    public String deleteDirectDevice(String deviceId) throws Exception {
		// Two-Way Authentication
		HttpsUtil httpsUtil = new HttpsUtil();
		httpsUtil.initSSLConfigForTwoWay();

		//Please make sure that the following parameter values have been modified in the Constant file.
		String appId = Constant.APPID;

        String urlDelete = Constant.DELETE_DEVICE + "/" +deviceId;
                
        Map<String, String> header = new HashMap<>();
        header.put(Constant.HEADER_APP_KEY, appId);
        header.put(Constant.HEADER_APP_AUTH, "Bearer" + " " + accessToken);
        
        StreamClosedHttpResponse responseDelete = httpsUtil.doDeleteGetStatusLine(urlDelete, header);

		logger.info("StatusLine:"+responseDelete.getStatusLine()+" response content:"+responseDelete.getContent());
        return responseDelete.getContent();
    }
    @SuppressWarnings("resource")
	public String lookAll() throws Exception {

        // Two-Way Authentication
        HttpsUtil httpsUtil = new HttpsUtil();
        httpsUtil.initSSLConfigForTwoWay();

        //Please make sure that the following parameter values have been modified in the Constant file.
		String appId = Constant.APPID;

        String urlDeviceActivationStatus = Constant.SUBSCRIBE_NOTIFYCATION ;

        Map<String, String> header = new HashMap<>();
        header.put(Constant.HEADER_APP_KEY, appId);
        header.put(Constant.HEADER_APP_AUTH, "Bearer" + " " + accessToken);

        StreamClosedHttpResponse bodyDeviceActivationStatus = httpsUtil.doGetWithParasGetStatusLine(
                urlDeviceActivationStatus, null, header);

        logger.info("StatusLine:"+bodyDeviceActivationStatus.getStatusLine()+" Content:"+bodyDeviceActivationStatus.getContent());
        return bodyDeviceActivationStatus.getStatusLine()+bodyDeviceActivationStatus.getContent();
    
    }
    
    public  String cmd(String deviceId,String serviceId,String method,int fDetectorAddress,int fDetectorType,int fCommandType,Integer fValue)  throws Exception {

        // Two-Way Authentication
        HttpsUtil httpsUtil = new HttpsUtil();
        httpsUtil.initSSLConfigForTwoWay();

        // Authentication，get token

        //Please make sure that the following parameter values have been modified in the Constant file.
        String urlPostAsynCmd = Constant.POST_ASYN_CMD;
        String appId = Constant.APPID;

        //please replace the deviceId, when you use the demo.
        String callbackUrl = Constant.REPORT_CMD_EXEC_RESULT_CALLBACK_URL;

//        String serviceId = "detectorStatus";
//        String method = "QueryStatus";
        int fCheckSum;
        JsonNodeFactory nodeFactory = new JsonNodeFactory(false);
        ObjectNode paras = new ObjectNode(nodeFactory);
	      paras.put("fDetectorAddress", fDetectorAddress);
	      paras.put("fDetectorType", fDetectorType);
	      paras.put("fCommandType", fCommandType);
	      fCheckSum=fCommandType+fDetectorType+fDetectorAddress;
	      if(fValue!=null) {
	    	  paras.put("fValue", fValue); 
	    	  fCheckSum=fValue+fCommandType+fDetectorType+fDetectorAddress;
	      }
	      paras.put("fCheckSum", fCheckSum);
//        paras.put("fDetectorAddress", 1);
//        paras.put("fDetectorType", 4);
//        paras.put("fCommandType", 1);
//        paras.put("fCheckSum", 6);
        
        Map<String, Object> paramCommand = new HashMap<>();
        paramCommand.put("serviceId", serviceId);
        paramCommand.put("method", method);
        paramCommand.put("paras", paras);      
        
        Map<String, Object> paramPostAsynCmd = new HashMap<>();
        paramPostAsynCmd.put("deviceId", deviceId);
        paramPostAsynCmd.put("command", paramCommand);
        paramPostAsynCmd.put("callbackUrl", callbackUrl);
        paramPostAsynCmd.put("expireTime", 0);
        paramPostAsynCmd.put("maxRetransmit", 2);
        
        String jsonRequest = JsonUtil.jsonObj2Sting(paramPostAsynCmd);
                
        Map<String, String> header = new HashMap<>();
        header.put(Constant.HEADER_APP_KEY, appId);
        header.put(Constant.HEADER_APP_AUTH, "Bearer" + " " + accessToken);
        
        HttpResponse responsePostAsynCmd = httpsUtil.doPostJson(urlPostAsynCmd, header, jsonRequest);

        String responseBody = httpsUtil.getHttpResponseBody(responsePostAsynCmd);

        logger.info("StatusLine:"+responsePostAsynCmd.getStatusLine()+" Content:"+responseBody);
        return responseBody;
    }
    
    public  String queryCmd()  throws Exception {
        // Two-Way Authentication
        HttpsUtil httpsUtil = new HttpsUtil();
        httpsUtil.initSSLConfigForTwoWay();

        //Please make sure that the following parameter values have been modified in the Constant file.
    	String appId = Constant.APPID;
        String urlQueryDeviceCMD = Constant.QUERY_DEVICE_CMD;
        
        Map<String, String> header = new HashMap<>();
        header.put(Constant.HEADER_APP_KEY, appId);
        header.put(Constant.HEADER_APP_AUTH, "Bearer" + " " + accessToken);
        
        StreamClosedHttpResponse responseQueryDeviceCMD = httpsUtil.doGetWithParasGetStatusLine(urlQueryDeviceCMD, null, header);
        
    	logger.info("StatusLine:"+responseQueryDeviceCMD.getStatusLine()+" Content:"+responseQueryDeviceCMD.getContent());
        return responseQueryDeviceCMD.getContent();
    }
    


}
